package com.superhero.miniprogram.security;

import com.superhero.common.repository.AuthUserRepository;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private final static Logger logger = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);

    @Resource
    private CustomUserService userService;
    @Resource
    private JwtTokenUtils jwtTokenUtils;
    @Resource
    private AuthUserRepository userRepository;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String authToken = request.getHeader("Authorization");
        logger.info("Token {}", authToken);
        String path = request.getRequestURI();
        // 是否请求头中带有token
        if (StringUtils.isNotBlank(authToken)) {
            String username = jwtTokenUtils.getUsernameFromToken(authToken);

            logger.info("检查授权 {}", username);
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                JwtAuthUser user = this.userService.loadUserByUsername(username);

                //检查token是否有效
                if (jwtTokenUtils.validateToken(authToken, user)) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    //设置用户登录状态
                    logger.info("已授权用户 {}", username);
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        filterChain.doFilter(request, response);
    }

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        List<String> skipList = new ArrayList<>();
        skipList.add("/miniprogram/auth/wxLogin");
        skipList.add("/miniprogram/auth/normalLogin");
        AntPathMatcher pathMatcher = new AntPathMatcher();
        return skipList.stream().anyMatch(p -> pathMatcher.match(p, request.getRequestURI()));
    }
}
